// 定制协议类
#pragma once

#include <iostream>
#include <memory>
#include<jsoncpp/json/json.h>

//#define SelfDefine

using namespace std;


namespace Protocol
{
    // 解决的问题
    // 1.结构化数据的序列化和反序列化
    // 2.解决用户区分报文边界——数据包粘报问题

    const string LineBreakSep = "\n"; // 报文边界
    const string  ProtSep= " ";   // 分割符

    //"len\nx op y\n” len报文的自描述问题（报头）
    string Encode(string &message)
    {
        string len=to_string(message.size());// 获取字符串的长度
        string package=len+LineBreakSep+message+LineBreakSep;
        return package;   
    }
    //我无法保证package就是一个独立完整的报文
    //可能
    //“l
    //"len
    //

    //除了解包，我还想判断报文的完整性，能否正确处理具有“边界”的报文
    bool Decode(string &package,string* message)
    {
        auto pos=package.find(LineBreakSep);
        if(pos==string::npos)return false;

        string lens=package.substr(0,pos);
        int messagelen=stoi(lens);

        int total=lens.size()+messagelen+2*LineBreakSep.size();
        if(package.size()<total) return false;

        //至少package内部有一个独立的报文
        *message=package.substr(pos+LineBreakSep.size(),messagelen);
       
        package.erase(0,total);//处理完一个报文后，将处理的报文删除
        return true;
    }   

    class Request
    {
    public:
        Request() : _data_x(0), _data_y(0), _oper(0)
        {
        }
        Request(int x, int y, char oper) : _data_x(x), _data_y(y), _oper(oper)
        {
        }
        void Debug()
        {
            std::cout << "Request: " << _data_x << " " << _data_y << " " << _oper << std::endl;
        }
        void Inc()
        {
            _data_x++;
            _data_y++;
        }
        // 序列化
        // 结构化的数据转化成字符串
        bool Serialize(string *out)
        {
            #ifdef SelfDefine
            *out = to_string(_data_x)  +  ProtSep + _oper+ ProtSep+to_string(_data_y) ;
            return true;
            #else
            Json::Value root;
            root["data_x"] = _data_x;
            root["data_y"] = _data_y;
            root["oper"] = _oper;

            Json::FastWriter writer;
            *out = writer.write(root);//???????

            return true;
            #endif

        }
        // 反序列化
        bool Deserialize(string &in) //"x op y"
        {
            #ifdef SelfDefine
            auto left = in.find(ProtSep);
            if (left == string::npos)
                return false;

            auto right = in.rfind(ProtSep);
            if (right == string::npos)
                return false;

            _data_x = stoi(in.substr(0, left));                // 获取第一个字符，并转为整数
            _data_y = stoi(in.substr(right + ProtSep.size())); // 获取第二个字符，并转为整数
            //_oper=in[left+ProtSep.size()];//获取第三个字符，并转为字符
            string oper = in.substr(left + ProtSep.size(), right - (left + ProtSep.size()));
            if (oper.size() != 1)
                return false;
            _oper = oper[0];
            return true;
            #else
            Json::Value root;
            Json::Reader reader;
            bool res=reader.parse(in, root);

            if (res)
            {
                _data_x = root["data_x"].asInt();//??????
                _data_y = root["data_y"].asInt();//???
                _oper = root["oper"].asInt();//???
                root["oper"];
            }
            return res;

            #endif
        }
        int GetX(){return _data_x;}
        int GetY(){return _data_y;}
        char GetOper(){return _oper;}
    private:
        //"len\nx op y\n” len报文的自描述问题（报头）
        int _data_x; // 第一个参数
        int _data_y; // 第二个参数
        char _oper;  // 算数运算符 + - * / %
    };

    class Reponse
    {
    public:
        Reponse() : _result(0), _code(0)
        {
        }
        Reponse(int result, int code) : _result(result), _code(code)
        {
        }

        // 序列化
        // 结构化的数据转化成字符串
        bool Serialize(string *out)
        {
            #ifdef SelfDefine
            *out = to_string(_result) + ProtSep + to_string(_code);
            return true;
            #else
            Json::Value root;
            root["result"] = _result;
            root["code"] = _code;

            Json::FastWriter writer;
            *out = writer.write(root);
            return true;
            #endif
        }
        // 反序列化
        bool Deserialize(string &in) //"_result _code"
        {
            #ifdef SelfDefine
            auto pos = in.find(ProtSep);
            if (pos == string::npos)
                return false;
            _result = stoi(in.substr(0, pos));
            _code = stoi(in.substr(pos + ProtSep.size()));
            return true;
            #else
            Json::Value root;
            Json::Reader reader;
            bool res = reader.parse(in, root);

            if (res)
            {
                _result = root["result"].asInt();
                _code = root["code"].asInt();
            }
            return res;
            #endif
        }
        void SetResult(int res){_result=res;}
        void SetCode(int code){_code=code;}
        int GetResult(){return _result;}
        int GetCode(){return _code;}
    private:
        //"len\nresult code\n”
        int _result; // 运算结果
        int _code;   // 状态码
    };

    // 工厂模式
    class Factory
    {
    public:
        shared_ptr<Request> BuildRequest()
        {
            shared_ptr<Request> req = make_shared<Request>();
            return req;
        }

        shared_ptr<Request> BuildRequest(int x, int y, char oper)
        {
            shared_ptr<Request> req = make_shared<Request>(x, y, oper);
            return req;
        }

        shared_ptr<Reponse> BuildReponse()
        {
            shared_ptr<Reponse> rep = make_shared<Reponse>();
            return rep;
        }
        shared_ptr<Reponse> BuildReponse(int result, int code)
        {
            shared_ptr<Reponse> rep = make_shared<Reponse>(result, code);
            return rep;
        }
    };
}